#include "event_based_object.hh"
#include "net_event.hh"
#include "../singleton.hpp"

using namespace kratos::corelib;

namespace kratos {
namespace network {

EventBasedObject::EventBasedObject() {
    EventBaseObjectLocatorRef.add(this);
}

EventBasedObject::~EventBasedObject() {
    EventBaseObjectLocatorRef.remove(getID());
}

void EventBasedObject::handleEvent(Event* event) {
    auto it = eventFuncMap_.find(event->getID());
    if (it == eventFuncMap_.end()) {
        return;
    }
    it->second(event);
}

void EventBasedObject::registerEventHandler(std::uint32_t eventID, EventHandler func) {
    eventFuncMap_[eventID] = func;
}

void EventBasedObject::unregisterEventHandler(std::uint32_t eventID) {
    auto it = eventFuncMap_.find(eventID);
    if (it != eventFuncMap_.end()) {
        eventFuncMap_.erase(it);
    }
}

EventBasedObjectLocator::EventBasedObjectLocator() {
}

EventBasedObjectLocator::~EventBasedObjectLocator() {
}

void EventBasedObjectLocator::add(EventBasedObject* object) {
    std::lock_guard<std::mutex> lock(lock_);
    objectMap_[object->getID()] = object;
}

void EventBasedObjectLocator::remove(std::uint32_t objectID) {
    std::lock_guard<std::mutex> lock(lock_);
    auto it = objectMap_.find(objectID);
    if (it == objectMap_.end()) {
        return;
    }
    objectMap_.erase(it);
}

EventBasedObject* EventBasedObjectLocator::getObject(std::uint32_t objectID) {
    std::lock_guard<std::mutex> lock(lock_);
    auto it = objectMap_.find(objectID);
    if (it == objectMap_.end()) {
        return nullptr;
    }
    return it->second;
}

}
}
